package com.longbig.multifunction.helper;

/**
 * @author Administrator
 * @date 2024/4/2 16:18
 * @description
 */

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

@Slf4j
public class EncryptTools {

//    private static String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJtCD1G4fj3H0bbBTkhQMvRx2vkmAPmcpsXfrSQSy9MfftPfJkSHdhUd990w7bYTQfWdc1NMUdX1cnQw4cP0VTvORgQ5EA0noXaT1lKTn24b6RNhhcAMjs7iSQ6pr8dQGeIiI5197y63bnU+pkb9gNkLoCmLOeBsJgStlZmKAk+RAgMBAAECgYANkT1Dd+rYPUDvRn8vxIpfYB+xjAejyHOucPhxYY8cOPFdVG/Ep03DVKYXVzI+qfomm4a7bbztBJDm5GqmNBDKkI+D5+dLvN+ffVKvP2BRNcderN+mffAWMkpCq1HftmUZJhwCAdQ5NZ6vVZf93iSEHQGyQL/2qAJusow6VJZ6wQJBAPRhBcxQKmp/xI66Kwy+sYJeJbqc/vawL4TpRBsDxcVSyiSxo02FKpC26+iz/yfv6dK4ZH8eS+pKbxBl/gB3atkCQQCipBzNbYTFS7KafcyxUXH9gwptohxtUp1Kqz9g60F/HoxhhdGyndKKZ2P0IIZotANQbST/2aDvajE3rKPy/+d5AkBCViv6wDAjZLd4fvS8qu8IkoHvXDqhwEXF8IQ6SRXgcI7K0yWfH2zkh6MWMfYrYya3urIdB55X5QitDOKcQc5RAkEAiviN/96H54nCCA5cHFuKemNBQuKVRbik3EutcSQ0J+mzbBVLVENUxpyHpO8xyj+e4VcRmWidAlYLzhW/VYDiiQJAfPVP+RtEjM9XlmsjxjKpWTVbpW5RYZUUeL+6TlAzXNiTML5BqVWKm/S4vA4js+7JDN1eoFTUb4szqdBavs+X8A==";
//    private static String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbQg9RuH49x9G2wU5IUDL0cdr5JgD5nKbF360kEsvTH37T3yZEh3YVHffdMO22E0H1nXNTTFHV9XJ0MOHD9FU7zkYEORANJ6F2k9ZSk59uG+kTYYXADI7O4kkOqa/HUBniIiOdfe8ut251PqZG/YDZC6ApizngbCYErZWZigJPkQIDAQAB";
//

//    public static void main(String[] args) {
//        String content = "{\"deviceType1\":\"switch\",\"downPortList\":[\"gigabitethernet0/0/2\",\"gigabitethernet0/0/3\",\"gigabitethernet0/0/4\",\"gigabitethernet0/0/5\",\"gigabitethernet0/0/6\",\"gigabitethernet0/0/7\",\"gigabitethernet0/0/8\",\"gigabitethernet0/0/9\",\"gigabitethernet0/0/10\",\"gigabitethernet0/0/11\",\"gigabitethernet0/0/12\",\"gigabitethernet0/0/13\",\"gigabitethernet0/0/14\",\"gigabitethernet0/0/15\",\"gigabitethernet0/0/16\",\"gigabitethernet0/0/17\",\"gigabitethernet0/0/18\",\"gigabitethernet0/0/19\",\"gigabitethernet0/0/20\",\"gigabitethernet0/0/21\",\"gigabitethernet0/0/22\",\"gigabitethernet0/0/23\",\"gigabitethernet0/0/24\",\"meth0/0/1\",\"vlanif1\"],\"ip\":\"192.168.56.2\",\"switchImageInfoList\":[[{\"imageType\":\"source_\",\"list\":[],\"port\":1,\"portName\":\"gigabitethernet0/0/1\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"镜像\"},{\"imageType\":\"target_\",\"list\":[],\"port\":2,\"portName\":\"gigabitethernet0/0/2\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"镜像\"}],[{\"imageType\":\"source_\",\"list\":[],\"port\":3,\"portName\":\"gigabitethernet0/0/3\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"镜像\"},{\"imageType\":\"target_\",\"list\":[],\"port\":6,\"portName\":\"gigabitethernet0/0/6\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"镜像\"}],[{\"imageType\":\"source_\",\"list\":[],\"port\":1,\"portName\":\"gigabitethernet0/0/1\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"重定向\"},{\"imageType\":\"target_\",\"list\":[],\"port\":3,\"portName\":\"gigabitethernet0/0/3\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"重定向\"}],[{\"imageType\":\"source_\",\"list\":[],\"port\":2,\"portName\":\"gigabitethernet0/0/2\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"重定向\"},{\"imageType\":\"target_\",\"list\":[],\"port\":5,\"portName\":\"gigabitethernet0/0/5\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"重定向\"}]]}";
//        String encrptContent = AESEncrypt(content);
//        String signKey = signBySHA256WithRSA(content, privateKey, "utf-8");
//        System.out.println(signKey);
//        System.out.println(encrptContent);
//        String content1 = "{\"deviceType1\":\"switch\",\"downPortList\":[\"gigabitethernet0/0/2\",\"gigabitethernet0/0/3\",\"gigabitethernet0/0/4\",\"gigabitethernet0/0/5\",\"gigabitethernet0/0/6\",\"gigabitethernet0/0/7\",\"gigabitethernet0/0/8\",\"gigabitethernet0/0/9\",\"gigabitethernet0/0/10\",\"gigabitethernet0/0/11\",\"gigabitethernet0/0/12\",\"gigabitethernet0/0/13\",\"gigabitethernet0/0/14\",\"gigabitethernet0/0/15\",\"gigabitethernet0/0/16\",\"gigabitethernet0/0/17\",\"gigabitethernet0/0/18\",\"gigabitethernet0/0/19\",\"gigabitethernet0/0/20\",\"gigabitethernet0/0/21\",\"gigabitethernet0/0/22\",\"gigabitethernet0/0/23\",\"gigabitethernet0/0/24\",\"meth0/0/1\",\"vlanif1\"],\"ip\":\"192.168.56.2\",\"switchImageInfoList\":[[{\"imageType\":\"source_\",\"list\":[],\"port\":1,\"portName\":\"gigabitethernet0/0/1\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"镜像\"},{\"imageType\":\"target_\",\"list\":[],\"port\":2,\"portName\":\"gigabitethernet0/0/2\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"镜像\"}],[{\"imageType\":\"source_\",\"list\":[],\"port\":3,\"portName\":\"gigabitethernet0/0/3\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"镜像\"},{\"imageType\":\"target_\",\"list\":[],\"port\":6,\"portName\":\"gigabitethernet0/0/6\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"镜像\"}],[{\"imageType\":\"source_\",\"list\":[],\"port\":1,\"portName\":\"gigabitethernet0/0/1\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"重定向\"},{\"imageType\":\"target_\",\"list\":[],\"port\":3,\"portName\":\"gigabitethernet0/0/3\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"重定向\"}],[{\"imageType\":\"source_\",\"list\":[],\"port\":2,\"portName\":\"gigabitethernet0/0/2\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"重定向\"},{\"imageType\":\"target_\",\"list\":[],\"port\":5,\"portName\":\"gigabitethernet0/0/5\",\"portPrefix\":\"gigabitethernet0/0\",\"portType\":\"1\",\"relationType\":\"重定向\"}]]}";
//        boolean signResult = verifyBySHA256WithRSA(content1, signKey, publicKey, "utf-8");
////        String contentWithoutSign = content.substring(0, content.length() - sign.length() - 49);
////        boolean verifyResult = EncryptTools.verifyBySHA256WithRSA(contentWithoutSign, sign, publicKey, "utf-8");
//        System.out.println(signResult);
//
//    }

    public static Map<String, String> generateKeys() {
        Map<String, String> resultMap = new HashMap<>();
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            keyPairGen.initialize(1024);
            KeyPair keyPair = keyPairGen.generateKeyPair();
            String privateKeyStr = new String(Base64.getEncoder().encode(keyPair.getPrivate().getEncoded()));
            String publicKeyStr = new String(Base64.getEncoder().encode(keyPair.getPublic().getEncoded()));
            resultMap.put("privateKey", privateKeyStr);
            resultMap.put("publicKey", publicKeyStr);
        } catch (NoSuchAlgorithmException e) {
            log.error("generate rsa keys error, message: {}", e.getMessage());
        }
        return resultMap;
    }

    public static String publicEncrypt(String content, String publicKeyStr) {
        try {
            PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(
                    Base64.getDecoder().decode(publicKeyStr.getBytes())));
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(1, pubKey);
            byte[] enBytes = cipher.doFinal(content.getBytes());
            String encryptStr = new String(Base64.getEncoder().encode(enBytes));
            return encryptStr;
        } catch (Exception e) {
            log.error("rsa encrypt exception: {}", e.getMessage(), e);
            return null;
        }
    }

    public static String privateDecrypt(String content, String privateKeyStr) {
        try {
            PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(
                    Base64.getDecoder().decode(privateKeyStr.getBytes())));
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(2, priKey);
            byte[] deBytes = cipher.doFinal(Base64.getDecoder().decode(content.getBytes()));
            return new String(deBytes);
        } catch (Exception e) {
            log.error("rsa decrypt exception: {}", e.getMessage(), e);
            return null;
        }
    }

    public static String signBySHA256WithRSA(String content, String privateKey, String charset) {
        if (StringUtils.isBlank(privateKey))
            return null;
        try {
            PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(
                    Base64.getDecoder().decode(privateKey.getBytes())));
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(priKey);
            signature.update(content.getBytes(charset));
            return new String(Base64.getEncoder().encode(signature.sign()));
        } catch (Exception e) {
            log.error("sign error, message: {}", e.getMessage(), e);
            return null;
        }
    }

    public static boolean verifyBySHA256WithRSA(String content, String signStr, String publicKey, String charSet) {
        if (StringUtils.isBlank(publicKey))
            return false;
        try {
            PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(
                    Base64.getDecoder().decode(publicKey.getBytes())));
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initVerify(pubKey);
            signature.update(content.getBytes("utf-8"));
            byte[] decode = Base64.getDecoder().decode(signStr.getBytes());
            return signature.verify(decode);
        } catch (Exception e) {
            log.error("verify sign error, message: {}", e.getMessage());
            return false;
        }
    }

    public static String signByParamMap(Map<String, String> params, String privateKey) {
        try {
            ArrayList<String> keyList = new ArrayList<>(params.keySet());
            Collections.sort(keyList);
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < keyList.size(); i++)
                sb.append(keyList.get(i)).append("=").append(params.get(keyList.get(i))).append("&");
            String paramStr = sb.toString().substring(0, sb.length() - 1);
            String sign = signBySHA256WithRSA(paramStr, privateKey, "utf-8");
            return URLEncoder.encode(sign, "utf-8");
        } catch (Exception e) {
            log.error("sign error, message: {}", e.getMessage());
            return null;
        }
    }

    public static boolean verify(Map<String, String> params, String publicKey) {
        try {
            if (!params.containsKey("sign"))
                return false;
            String sign = params.get("sign");
            params.remove("sign");
            ArrayList<String> keyList = new ArrayList<>(params.keySet());
            Collections.sort(keyList);
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < keyList.size(); i++)
                sb.append(keyList.get(i)).append("=").append(params.get(keyList.get(i))).append("&");
            String paramStr = sb.toString().substring(0, sb.length() - 1);
            return verifyBySHA256WithRSA(paramStr, sign, publicKey, "utf-8");
        } catch (Exception e) {
            log.error("verify sign error, message: {}", e.getMessage());
            return false;
        }
    }

    private static String AESKey = "UITN25LM334636IM";

    public static String AESEncrypt(String content) {
        try {
            Cipher encodeCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            encodeCipher.init(1, new SecretKeySpec(AESKey.getBytes(StandardCharsets.UTF_8), "AES"));
            byte[] encrypt = encodeCipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
            String encryptStr = new String(Base64.getEncoder().encode(encrypt));
            return encryptStr;
        } catch (Exception e) {
            log.error("AESEncrypt error, message: {}", e.getMessage());
            return null;
        }
    }

    public static String AESDecrypt(String encryptStr) {
        try {
            Cipher decodeCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            decodeCipher.init(2, new SecretKeySpec(AESKey.getBytes(StandardCharsets.UTF_8), "AES"));
            byte[] decrypt = decodeCipher.doFinal(Base64.getDecoder().decode(encryptStr));
            String decryptStr = new String(decrypt, StandardCharsets.UTF_8);
            return decryptStr;
        } catch (Exception e) {
            log.error("AESEncrypt error, message: {}", e.getMessage());
            return null;
        }
    }
}

